//
//  CoreDataManager.m
//  LineByLine
//
//  Created by 병철 김 on 11. 10. 11..
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "CoreDataManager.h"
#import "CommonUtil.h"


@implementation CoreDataManager

@synthesize managedObjectContext, managedObjectModel, persistentStoreCoordinator;

+ (CoreDataManager *)sharedCoreDataManager
{
    static dispatch_once_t onceToken;
    static CoreDataManager *sharedInstance = nil;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[self alloc] init];
    });
    
    return sharedInstance;
}

- (void)dealloc {
    [managedObjectContext release];
    [managedObjectModel release];
    [persistentStoreCoordinator release];
    [super dealloc];
}

- (void) save {
    NSError *error;
    BOOL isSuccess = [managedObjectContext save:&error];
    if (!isSuccess && error != nil) {
        NSLog(@"%@", error);
    }
}

- (NSManagedObject*) insertNewObject:(NSString*)entity {
	NSManagedObject *newObject = [NSEntityDescription insertNewObjectForEntityForName:entity inManagedObjectContext:managedObjectContext];
	return newObject;
}

- (NSEntityDescription*) getEntity:(NSString*) entityName {
    return [NSEntityDescription entityForName:entityName inManagedObjectContext:managedObjectContext];
}

- (NSPredicate*) getPredicate:(id)values :(va_list)args {
	NSPredicate *predicate = [NSPredicate predicateWithFormat:values arguments:args];
	return predicate;
}

- (id) executeFetchRequest:(NSFetchRequest*)fetchRequest context:(NSManagedObjectContext*)context {
	NSError *error;
	NSArray *result = [context executeFetchRequest:fetchRequest error:&error];
	
	if (!result && error) {
		NSLog(@"executeFetchRequest Error : %@", [error userInfo]);
	}
	return result;
}

/* ... 파라미터를 넘길 방법이 없어 중복 코드 작성 OTL */
- (id)selectOneFrom:(NSString*)entityName where:(id)condition, ... {
    NSEntityDescription *entity = [self getEntity:entityName];
    
    va_list args;
	va_start(args, condition);
    NSPredicate *predicate = [self getPredicate:condition :args];
    va_end(args);
    
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setEntity:entity];
    if (predicate != nil) {
		[fetchRequest setPredicate:predicate];
	}
    NSArray *result = [self executeFetchRequest:fetchRequest context:managedObjectContext];
    [fetchRequest release];
    
    if ([result count] > 0) {
        return [result objectAtIndex:0];
    } else {
        return nil;
    }
}

- (NSArray*)selectFrom:(NSString*)entityName where:(id)condition, ... {
    NSEntityDescription *entity = [self getEntity:entityName];
    
    va_list args;
	va_start(args, condition);
    NSPredicate *predicate = [self getPredicate:condition :args];
    va_end(args);
    
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setEntity:entity];
    if (predicate != nil) {
		[fetchRequest setPredicate:predicate];
	}
    NSArray *result = [self executeFetchRequest:fetchRequest context:managedObjectContext];
    [fetchRequest release];
    
    return result;
}

- (id)insertOneInto:(NSString*)entityName values:(id)values, ... {
    id newObject = [self insertNewObject:entityName];
    
    va_list args;
	va_start(args, values);
    [CommonUtil setKeyValuesTo:newObject first:values valist:args];
    va_end(args);
    
    [self save];
    return newObject;
}

- (void) update:(id)object values:(id) values, ... {
    va_list args;
	va_start(args, values);
    [CommonUtil setKeyValuesTo:object first:values valist:args];
    va_end(args);
    
    [self save];
}

- (NSArray*) storeBooks {
    return [self selectFrom:@"StoreBook" where:nil];
}

@end
